      <h1 class="entry-title entry-title-single" itemprop="headline">ABAP 开发系列(10): Function Module</h1>

    <div class="entry-content entry-content-single entry-content-aside" itemprop="text">
      <p><b>内容包括：</b></p>
<p>1. <span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/function" title="Function" target="_blank">Function</a></span> Module概述</p>
<p>2. <span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/function" title="Function" target="_blank">Function</a></span> Group</p>
<p>3. <span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/function" title="Function" target="_blank">Function</a></span> Module的操作</p>
<p>4. <span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/rfc" title="查看RFC中的全部文章" target="_blank">RFC</a></span> (Remote <span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/function" title="查看Function中的全部文章" target="_blank">Function</a></span> Call)</p>
<p>5. 创建<span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/function" title="Function Module" target="_blank">Function Module</a></span>实例</p>
<p>6. <span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/bapi" title="abap bapi" target="_blank">BAPI</a></span></p>
<p>&nbsp;</p>
<p><span id="more-399"></span></p>
<h2><b>1. <span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/function" title="Function Module" target="_blank">Function Module</a></span> </b><b>概述</b></h2>
<p><span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/function" title="查看Function中的全部文章" target="_blank">Function</a></span> Module是模块化（Modularization）的另一种单元，也叫<span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/function" title="函数" target="_blank">函数</a></span>模块，一般简称为<span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/function" title="函数" target="_blank">函数</a></span>（FM）。</p>
<p><span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/sap" title="SAP" target="_blank">SAP</a></span> R/3系统提供了Function Library（FL）来封装Function Module，而每个Function Module 都会有一个输入/输出参数的接口供程序调用传输。</p>
<p>能多次独立或直接被<span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/sap" title="SAP" target="_blank">SAP</a></span>其他程序调用，强调了其可复用性。</p>
<p>Function Module也支持远程访问模式，即：Remote Function Call（<span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/rfc" title="查看RFC中的全部文章" target="_blank">RFC</a></span>），提供外部接口供非SAP系统使用；</p>
<p>同时，SAP官方也提供了 JCO(Java Connector)、NCO(.Net Connector)等组件与SAP RFC通信。</p>
<p>下面介绍 Function Module 的操作及相关应用。</p>
<p>&nbsp;</p>
<h2><b>2. </b><b>函数组（<span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/function-group" title="查看Function Group中的全部文章" target="_blank">Function Group</a></span>s</b><b>）</b></h2>
<p>每个Function Module都必须指定分属<span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/function-group" title="查看Function Group中的全部文章" target="_blank">Function Group</a></span>，用于区分函数操作类别。</p>
<p>一般情况下，<span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/function-group" title="查看Function Group中的全部文章" target="_blank">Function Group</a></span>定义的都是操作类似的Function Module，包括一系列组件：</p>
<p>&nbsp;</p>
<p><b>1). </b><b>数据对象（Data Objects</b><b>）</b></p>
<p>Function Group的全局变量、内表、结构、类等对象，可通用于整个Function Group；</p>
<p><b>2). </b><b>子程序（Subroutine</b><b>）</b></p>
<p>创建的子程序可被在该Function Group内的 Function Module 调用；</p>
<p><b>3). </b><b>屏幕（Screens</b><b>）</b></p>
<p>创建的屏幕可被在该Function Group内的Function Module使用；</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Function_Group_Object_Name.png" alt="abap_10_FM_Function_Group_Object_Name" width="484" height="257" class="alignnone size-full wp-image-422" /></p>
<p>&nbsp;</p>
<h2><b>2.1 </b><b>创建Function Group</b></h2>
<p>1). 通过T-Code：SE37，进入Function Builder的初始界面：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Function_Builder_Initial_Screen.png" alt="abap_10_FM_Function_Builder_Initial_Screen" width="463" height="210" class="alignnone size-full wp-image-421" /></p>
<p>2) 通过菜单栏路径：<b>Goto -&gt; Function Groups -&gt; Create Groups</b></p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Create_Function_Group_Location.png" alt="abap_10_FM_Create_Function_Group_Location" width="533" height="264" class="alignnone size-full wp-image-420" /></p>
<p>（除了Create Group外，还有 Change Group、Display Group、Delete Group、Find Group，分别用于修改、显示、删除、查找Function Group属性信息）</p>
<p>选择Create Group之后，会弹出 “Create Function Group” 的对话框：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Create_Function_Group.png" alt="abap_10_FM_Create_Function_Group" width="518" height="206" class="alignnone size-full wp-image-419" /></p>
<p>输入Function Group名称及描述后保存按钮。</p>
<p>弹出 “Create Object Directory Entry” 对话框，要求存放在哪个开发包（Package）里面，因为为测试Demo，故点击“本地对象（Local Object）”即可。</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Create_Object_Directory_Entry.png" alt="abap_10_FM_Create_Object_Directory_Entry" width="518" height="272" class="alignnone size-full wp-image-418" /></p>
<p>&nbsp;</p>
<p>3）保存成功后，系统会在状态栏上弹出提示：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Create_Success_Status.png" alt="abap_10_FM_Create_Success_Status" width="691" height="29" class="alignnone size-full wp-image-417" /></p>
<p>&nbsp;</p>
<h2><b>3.  Function Module 的操作</b></h2>
<p>每个Function Module的接口都会包含以下元素：</p>
<p><b>1). Import Parameter</b>（输入参数）</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Import_Parameter.png" alt="abap_10_FM_Import_Parameter" width="851" height="182" class="alignnone size-full wp-image-416" /></p>
<p>调用 Function Module 时，外部传入的参数；</p>
<p>如若勾选参数中的Option选项，则该参数为非必输，如若不勾选，则表示必输。</p>
<p>定义传入参数与定义变量时一样，可用Like语句参考数据字典中的类型，如若用TYPE定义，Associated Type可以是基本类型，也可以是预定义类型。</p>
<p>&nbsp;</p>
<p><b>2). Export Parameter</b> （输出参数）</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Export_Parameter.png" alt="abap_10_FM_Export_Parameter" width="810" height="171" class="alignnone size-full wp-image-415" /></p>
<p>当 Function Module 处理完数据逻辑后，返回输出的参数；</p>
<p>不仅可返回变量，也可返回结构。</p>
<p>&nbsp;</p>
<p><b>3). Changing Parameter</b></p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Changing_Parameter.png" alt="abap_10_FM_Changing_Parameter" width="755" height="164" class="alignnone size-full wp-image-414" /></p>
<p>作为输入参数传入 Function Module 操作后，修改并作为返回输出的参数；</p>
<p>&nbsp;</p>
<p><b>4). Tables </b></p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Tables_Parameter.png" alt="abap_10_FM_Tables_Parameter" width="810" height="179" class="alignnone size-full wp-image-413" /></p>
<p>可传输内表作为数据源，Function Module 处理完成后，返回结果集。</p>
<p>&nbsp;</p>
<p><b>5). Exceptions</b> （异常）</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Exceptions_Parameter.png" alt="abap_10_FM_Exceptions_Parameter" width="702" height="164" class="alignnone size-full wp-image-412" /></p>
<p>设定异常参数，在 Function Module 处理过程中，自定义异常输出。</p>
<p>&nbsp;</p>
<p><h><b>3.1 Calling Function Module</b></h2>
<p>Function Module 可以被不同的程序重复调用，避免了不同系统相同功能代码的重复开发。</p>
<p>然而在开发过程中，不可能每个函数的Import参数和Export参数都能记住，可以使用 <span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/sap-abap" title="ABAP" target="_blank">ABAP</a></span> 的Pattern方式调用 Function Module。</p>
<p>操作步骤：</p>
<p>1) 将光标聚焦在需要Call Function的地方;</p>
<p>2) 点击<span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/sap-abap" title="ABAP" target="_blank">ABAP</a></span>编辑器工具栏中的 ”Pattern“按钮：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Pattern_Toolbar.png" alt="abap_10_FM_Pattern_Toolbar" width="604" height="34" class="alignnone size-full wp-image-423" /></p>
<p>弹出对话框，在CALL  FUNCTION 栏位输入函数名称并单击确定：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Pattern_Dialog.png" alt="abap_10_FM_Pattern_Dialog" width="582" height="404" class="alignnone size-full wp-image-411" /></p>
<p>3) 编辑器中会出现Function 相应的接口参数：</p>
<pre class="brush: abap;">

CALL FUNCTION 'LAST_DAY_OF_MONTHS'
  EXPORTING
    day_in                  =
* IMPORTING
*   LAST_DAY_OF_MONTH       =
* EXCEPTIONS
*   DAY_IN_NO_DATE          = 1
*   OTHERS                  = 2
          .
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

</pre>
<p>系统会将Function必输项作为默认的输入项。</p>
<p>&nbsp;</p>
<p><b style="color:red;">注意：</b></p>
<p><b style="color:red;">原先定义的Export接口变为了程序中的Importing 参数；Import接口在程序中变为了Exporting参数：</b></p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Import_Exporting.png" alt="abap_10_FM_Import_Exporting" width="494" height="285" class="alignnone size-full wp-image-410" /></p>
<p>&nbsp;</p>
<p><b>3.2 </b><b>异常处理</b></p>
<p>在Function Module中的Exception接口中，定义异常参数：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Exceptions_Process.png" alt="abap_10_FM_Exceptions_Process" width="581" height="206" class="alignnone size-full wp-image-409" /></p>
<p>然后在程序处理过程，如若出现异常，可以通过<b> Raise </b><b>语句 </b>输出异常：</p>
<pre class="brush: abap;">

FUNCTION STRING_SPLIT. 
  ...
  IF ...
     RAISE NO_DATA.
  ENDIF.

</pre>
<p>在调用函数时，通过EXCEPTIONS接口抛出异常</p>
<pre class="brush: abap;">

CALL FUNCTION 'STRING_SPLIT'
  EXPORTING
    delimiter = '-'
    string    = text
  IMPORTING
    head      = head
    tail      = tail
  EXCEPTIONS
    not_found = 1
    not_valid = 2
    too_long  = 3
    too_small = 4
    OTHERS    = 5.

</pre>
<p>&nbsp;</p>
<h2><b>4. RFC (Remote Function Call)</b></h2>
<p>RFC是 Function Module 类型的一种，区别在于处理的类型为 Remote，在 Function Module 的Attribute属性中可以看到：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_RFC.png" alt="abap_10_FM_RFC" width="692" height="412" class="alignnone size-full wp-image-408" /></p>
<p>RFC允许该Function被SAP与非SAP程序调用，是SAP与外部应用系统的通信接口。</p>
<p>&nbsp;</p>
<p>示例：</p>
<pre class="brush: abap;">
DATA:  INFO LIKE RFCSI,       "Importing parameter
       MSG_TEXT(80) TYPE C.   "Message text
 ...

CALL FUNCTION 'RFC_SYSTEM_INFO'   
DESTINATION 'NONE' 
 IMPORTING 
    RFCSI_EXPORT = INFO 
 EXCEPTIONS 
    COMMUNICATION_FAILURE = 1
    SYSTEM_FAILURE        = 2 .

IF SY-SUBRC NE 0. 

    WRITE: MSG_TEXT. 

ELSE. 

   WRITE: 'O.K.'. 

ENDIF. 

...

</pre>
<p>通过DESTINATION定义不同的源，连接外部系统。</p>
<p>&nbsp;</p>
<h2><b>5. 创建Function Module</b><b>实例</b></h2>
<p>下面通过示例创建一个Function Module：</p>
<p>操作步骤：</p>
<p>1) 通过T-Code：SE37进入Function Builder，输入Function Module名称（以Z开头），点击Create：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Create_Function_Module_Initial_Screen_Demo.png" alt="abap_10_FM_Create_Function_Module_Initial_Screen_Demo" width="461" height="123" class="alignnone size-full wp-image-407" /></p>
<p>弹出 “Create Function Module”对话框，输入上面创建好的Function Group及 Function Module 描述：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Create_Function_Module_Demo.png" alt="abap_10_FM_Create_Function_Module_Demo" width="558" height="140" class="alignnone size-full wp-image-406" /></p>
<p>2) 点击确认后，会提示弹出对话框，表示该 Function Module 已被SAP保留：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Create_Function_Module_Information_Demo.png" alt="abap_10_FM_Create_Function_Module_Information_Demo" width="494" height="140" class="alignnone size-full wp-image-405" /></p>
<p>&nbsp;</p>
<p>3) 切换到Attribute选项卡，选择处理类型：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Create_Function_Module_Attribute_Demo.png" alt="abap_10_FM_Create_Function_Module_Attribute_Demo" width="696" height="444" class="alignnone size-full wp-image-404" /></p>
<p><b>a). Normal Function Module</b>：普通调用模式，该Function在SAP系统中使用；</p>
<p><b>b). Remote-Enabled Module</b>：开启Remote功能，即远程调用模式，RFC</p>
<p><b>c). Update Module</b>：将该 Function Module 设置为Update 模式，调用该模式，可使用Update语句：</p>
<p><b>CALL FUNCTION  ‘FMXXX’  IN UPDATE TASK</b></p>
<p>必须每次使用COMMIT命令时才能完成数据操作。</p>
<p>这里保持默认设置即可。</p>
<p>&nbsp;</p>
<p>4) 输入接口参数（Import/Export/Changing/Tables参数）</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Create_Function_Module_Import_Demo.png" alt="abap_10_FM_Create_Function_Module_Import_Demo" width="788" height="145" class="alignnone size-full wp-image-403" /></p>
<p>&nbsp;</p>
<p>5) 编辑程序后，激活程序：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Create_Function_Module_Source_Demo.png" alt="abap_10_FM_Create_Function_Module_Source_Demo" width="673" height="247" class="alignnone size-full wp-image-402" /></p>
<p>&nbsp;</p>
<p>6) 调用程序：</p>
<pre class="brush: abap;">

CALL FUNCTION 'ZSAPJX_FM'
  EXPORTING
    ip_date = '20140101'.

</pre>
<p>&nbsp;</p>
<h2><b>6. <span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/bapi" title="abap bapi" target="_blank">BAPI</a></span></b></h2>
<p><span class='wp_keywordlink'><a href="http://www.sapjx.com/tag/bapi" title="abap bapi" target="_blank">BAPI</a></span>的全程为Business Application Process Interface，实质上是一种特殊的RFC，通过<span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/bapi" title="查看BAPI中的全部文章" target="_blank">BAPI</a></span>能够完成一些特殊的商业任务。</p>
<p>可以通过<span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/bapi" title="查看BAPI中的全部文章" target="_blank">BAPI</a></span>批量维护、处理业务数据。</p>
<p>&nbsp;</p>
<p>SAP R/3系统提供了大量的<span class='wp_keywordlink_affiliate'><a href="http://www.sapjx.com/tag/bapi" title="查看BAPI中的全部文章" target="_blank">BAPI</a></span>，可以通过BAPI浏览器查找（T-Code：BAPI），可以将操作对象按实际业务进行分组：</p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Bapi_Explorer.png" alt="abap_10_FM_Bapi_Explorer" width="689" height="605" class="alignnone size-full wp-image-401" /></p>
<p>&nbsp;</p>
<p>例如，查找取物料明细的BAPI：<b>Logistic &#8211; General -&gt; Logistic Basic Data -&gt; Material -&gt; GetDetail</b></p>
<p><img src="http://www.sapjx.com/wp-content/uploads/2014/03/abap_10_FM_Bapi_GetDetail.png" alt="abap_10_FM_Bapi_GetDetail" width="754" height="429" class="alignnone size-full wp-image-400" /></p>
<p>双击Function Module名称即可查看BAPI的相应的接口参数。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>